package my.demo.service.impl;

import cn.hutool.extra.qrcode.QrCodeUtil;
import cn.hutool.json.JSONUtil;
import my.demo.service.WXService;
import org.springframework.http.HttpEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;


@Service
public class WXServiceImpl implements WXService {
    private final String appletAppid = "小程序的appid";
    private final String appletSecret = "小程序的密钥";
    private final String officialAppid = "公众号的appid";
    private final String officialSecret = "公众号的密钥";
    private final String doMainName = "业务域名";
    public void getAppletOpenid(String code) {
        RestTemplate restTemplate = new RestTemplate();
        String codeJson = restTemplate.getForObject("https://api.weixin.qq.com/sns/jscode2session" +
                "?appid=" + appletAppid +
                "&secret=" + appletSecret +
                "&js_code=" + code +
                "&grant_type=authorization_code", String.class);
        Map result = JSONUtil.parseObj(codeJson).toBean(Map.class);
        if (result.get("openid") != null){
            saveOpenid(result.get("openid").toString());
        }else {
            throw new RuntimeException("openid获取失败， 错误码:" + result.get("errcode") + " 错误信息:" + result.get("errmsg"));
        }
    }

    public void appletSendMessage() {
        String accessToken = getAccessToken(appletAppid, appletSecret);
        RestTemplate restTemplate = new RestTemplate();
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("touser", "用户的openid");
        map.put("template_id", "选用模板id");
        // 模板数据
        Map<String, Object> data = new HashMap<String, Object>();
        data.put("thing1", Collections.singletonMap("value", "测试订阅推送"));
        data.put("number2", Collections.singletonMap("value", 10001));
        data.put("amount3", Collections.singletonMap("value", "100元"));
        data.put("thing4", Collections.singletonMap("value", "测试订单消息推送"));
        map.put("data", data);
        HttpEntity<Map<String, Object>> request = new HttpEntity<Map<String, Object>>(map);
        String resultJson = restTemplate.postForObject("https://api.weixin.qq.com/cgi-bin/message/subscribe/send" +
                "?access_token=" + accessToken, request, String.class);
        Map result = JSONUtil.parseObj(resultJson).toBean(Map.class);
        if (Integer.parseInt(result.get("errcode").toString()) != 0){
            throw new RuntimeException("发送失败， 错误码:" + result.get("errcode") + " 错误信息:" + result.get("errmsg"));
        }
    }

    public void officialAuth(HttpServletResponse response) {
        String redirectUrl = URLEncoder.encode("https://" + doMainName + "/wx/official/send");
        String url = "https://mp.weixin.qq.com/mp/subscribemsg" +
                "?action=get_confirm" +
                "&appid=" + officialAppid +
                "&scene=" + "0001" +
                "&template_id=" + "接口权限列表处一次性订阅消息模板id" +
                "&redirect_url=" + redirectUrl +
                "#wechat_redirect";
        response.setContentType("image/png");
        try {
            QrCodeUtil.generate(url,300,300,"jpg",response.getOutputStream());
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public void getOfficialOpenid(Map<String, Object> params) {
        String openid = params.get("openid").toString();
        if (openid != null){
            saveOpenid(openid);
        }else {
            String action = "confirm".equals(params.get("action").toString()) ? "确定授权" : "取消授权";
            throw new RuntimeException("openid获取失败， 用户行为:" + action);
        }
    }

    public void officialSendMessage() {
        String accessToken = getAccessToken(officialAppid, officialSecret);
        RestTemplate restTemplate = new RestTemplate();
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("touser", "用户openid");
        map.put("template_id", "接口权限列表处一次性订阅消息模板id");
        map.put("title", "阅读消息推送");
        map.put("scene", "0001");
        map.put("data", Collections.singletonMap("content", Collections.singletonMap("value", "文章制作不易，请留下一个小赞，谢谢。")));
        String resultJson = restTemplate.postForObject("https://api.weixin.qq.com/cgi-bin/message/template/subscribe?access_token=" + accessToken, map, String.class);
        Map result = JSONUtil.parseObj(resultJson).toBean(Map.class);
        if (Integer.parseInt(result.get("errcode").toString()) != 0){
            throw new RuntimeException("发送失败， 错误码:" + result.get("errcode") + " 错误信息:" + result.get("errmsg"));
        }
    }

    public void officialRouter(HttpServletResponse response) {
        String redirectUrl = URLEncoder.encode("https://" + doMainName + "/wx/official/login");
        String url = "https://open.weixin.qq.com/connect/oauth2/authorize" +
                "?appid=" + officialAppid +
                "&redirect_uri=" + redirectUrl +
                "&response_type=code" +
                "&scope=snsapi_base" +
                "&state=" + "0001" +
                "#wechat_redirect";
        response.setContentType("image/png");
        try {
            QrCodeUtil.generate(url,300,300,"jpg",response.getOutputStream());
        }catch (IOException e){
            throw new RuntimeException(e);
        }
    }

    public void officialLogin(Map<String, Object> params) {
        RestTemplate restTemplate = new RestTemplate();
        String resultJson = restTemplate.getForObject("https://api.weixin.qq.com/sns/oauth2/access_token" +
                "?appid=" + officialAppid +
                "&secret=" + officialSecret +
                "&code=" + params.get("code").toString() +
                "&grant_type=authorization_code", String.class).toString();
        Map result = JSONUtil.parseObj(resultJson).toBean(Map.class);
        if (result.get("openid") != null){
            saveOpenid(result.get("openid").toString());
        }else {
            throw new RuntimeException("openid获取失败， 错误码:" + result.get("errorcode") + "错误信息：" + result.get("errmsg"));
        }
    }

    public void officialTemplateSend() {
        String accessToken = getAccessToken(officialAppid, officialSecret);
        RestTemplate restTemplate = new RestTemplate();
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("touser", "用户openid");
        map.put("template_id", "公众号下模板消息的模板id");
        Map<String, Object> data = new HashMap<String, Object>();
        data.put("thing3", Collections.singletonMap("value", "测试模板"));
        data.put("thing13", Collections.singletonMap("value", "张三"));
        data.put("thing6", Collections.singletonMap("value", "李四"));
        data.put("time5", Collections.singletonMap("value", "2024-07-30"));
        map.put("data", data);
        String resultJson = restTemplate.postForObject("https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=" + accessToken, map, String.class);
        Map result = JSONUtil.toBean(resultJson, Map.class);
        if (0 != Integer.parseInt(result.get("errcode").toString())){
            throw new RuntimeException("发送失败， 错误码:" + result.get("errcode") + " 错误信息:" + result.get("errmsg"));
        }
    }

    private String getAccessToken(String appid, String secret){
        // 这里可以结合redis进行缓存
        RestTemplate restTemplate = new RestTemplate();
        String accessTokenJson = restTemplate.getForObject("https://api.weixin.qq.com/cgi-bin/token" +
                "?grant_type=client_credential" +
                "&appid=" + appid +
                "&secret=" + secret, String.class);
        Map result = JSONUtil.parseObj(accessTokenJson).toBean(Map.class);
        if (result.get("access_token") != null){
            return result.get("access_token").toString();
        }else {
            throw new RuntimeException("凭证获取失败， 错误码:" + result.get("errcode") + " 错误信息:" + result.get("errmsg"));
        }
    }
    private void saveOpenid(String openid){
        System.out.println("用户的openid:" + openid + " 获取成功");
    }
}
